import java.util.ArrayList;
import java.util.HashMap;

public class Manager {
	// HashMap for generating graphs.
	// FL stands for fall lecture; FT stands for fall tutorial
	private HashMap<String, ArrayList<Node>> FLNodes;
	private HashMap<String, ArrayList<Node>> SLNodes;

	private HashMap<String, ArrayList<Node>> FTNodes;
	private HashMap<String, ArrayList<Node>> STNodes;

	// Lists of the combinations of year sections
	// L stands for lectures and T stands for tutorials
	// Previous form: private ArrayList<Node> lectureStartNodes;
	private ArrayList<ArrayList<Node>> LYearSections;
	private ArrayList<ArrayList<Node>> TYearSections;

	// Completed timetables; FL stands for lectures for the fall semester
	// This collection contains nodes for the completed
	// time table of Lectures/Tutorials for a year

	private ArrayList<Node> FLTimeTable;
	private ArrayList<Node> FTTimeTable;

	private ArrayList<Node> SLTimeTable;
	private ArrayList<Node> STTimeTable;

	private Persona p;

	TimeTable FLttb;
	TimeTable SLttb;
	TimeTable FTttb;
	TimeTable STttb;

	// The example of FSYList {{"csc324H1", "csc258h1", "mat235h1"},{"csc321",
	// "sta257", "sta331"},{"lin100y1", "mat235y1"}}

	public Manager(ArrayList<ArrayList<String>> FSYList, Persona p) {
		// initiation
		FLNodes = new HashMap<String, ArrayList<Node>>();
		SLNodes = new HashMap<String, ArrayList<Node>>();

		FTNodes = new HashMap<String, ArrayList<Node>>();
		STNodes = new HashMap<String, ArrayList<Node>>();

		// update the FLNodes,SLNodes,FTNodes and STNodes
		ParseDataBase(FSYList);

		// Update L;T yearSections
		LYearSections = getYearSections(FLNodes);
		TYearSections = getYearSections(FTNodes);

		// Set persona
		this.p = p;

		//Initiate TimeTable objects 
		// FLttb = new TimeTable('L', FLNodes, null, p);
		FLttb = new TimeTable(LYearSections, FLNodes, null, p);
		SLttb = new TimeTable(LYearSections, SLNodes, null, p);
		FTttb = new TimeTable(TYearSections, FTNodes, null, p);
		STttb = new TimeTable(TYearSections, STNodes, null, p);
		
	}
	
	private void updateAllPersonas(Persona p){
		//update Persona for all timetable objects
		FLttb.updatePersona(p);
		SLttb.updatePersona(p);
		FTttb.updatePersona(p);
		STttb.updatePersona(p);
	}

	private void generateCompleteTimeTable() {
		//generate a complete timetable
		
		//glue timetable for F sections and S sections for lectures
		//result: either FLttb and SLttb has a complete timetables for the lecture
		//or at least one of them has conflict timetable but it can't be resolved
		//because there is no element in the yearSections left 
		glueTimeTables(FLttb, SLttb);
		
		//after making a timetable for both sections for the lectures
		//it is necessary to update fixed nodes for the timetable
		//objects for tutorials according to the timetable generated 
		//for the lecture
		FTttb.updateFixed(FLttb.getTimeTable());
		STttb.updateFixed(SLttb.getTimeTable());
		
		//if tutorial timetable for the both sections can't be generated
		//and if there is some elements left in the yearSections in 
		//the timetable object for lecture(i.e.,FLttb.isPossibletoProceed() )
		if (glueTimeTables(FTttb, STttb) == false
				&& FLttb.isPossibletoProceed()) {
			//update yearSections in the timetable objects for lectures
			//(i.e., we should try different combination of year sections)
			FLttb.updateYearSections();
			SLttb.updateYearSections();
			generateCompleteTimeTable();
		}
		//return best possible timetables
		FLTimeTable = FLttb.getTimeTable();
		SLTimeTable = SLttb.getTimeTable();
		FTTimeTable = FTttb.getTimeTable();
		STTimeTable = STttb.getTimeTable();
	}

	private boolean glueTimeTables(TimeTable t1, TimeTable t2) {
		//glue FL and SL or FT and ST together
		//FL stands for the timetable for the lectures in fall semester
		//FT stands for the timetable for the tutorials in fall semester
		
		//generate a timetable for t1
		t1.generateTTB();
		//if t1 got conflict and still has combinations for in yearSections 
		//try again to generate another timetable for t1 and update yearSection
		//for t2
		while (!t1.isWorkComplete()) {
			t1.tryAgain();
			t2.updateYearSections();
		}
		//generate a timetable for t2
		t2.generateTTB();
		//if t2 got conflict and t1 still has combinations in yearSections 
		//then update yearSections for both t1 and t2 and try to glue them again
		if (t2.isConflict() && t1.isPossibletoProceed()) {
			t1.updateYearSections();
			t2.updateYearSections();
			glueTimeTables(t1, t2);
			//if t1 or t2 got conflict and t1 doesn't have any combinations
			//in yearSections left
			//then gluing two timetable is failed and return false
		} else if (t2.isConflict() || t1.isConflict()) {
			return false;
		}
		//if t1 is not conflict and t2 is not conflict then return true
		return true;
	}

	
	// {{"csc2"}}
	public String[][] getTimeTable() {
		// put tutoTimeTable and lectureTimetable in the desired format.
		return null;
	}

	private ArrayList<ArrayList<Node>> getYearSections(
			HashMap<String, ArrayList<Node>> lectureNodes2) {
		// return a list of all combinations of year sections
		return null;
	}

	private void ParseDataBase(ArrayList<ArrayList<String>> fSList) {
		// parse the data Base and generate nodes for FLNodes,SLNodes,FTNodes and STNodes
	}

}
